package com.stars.module.login.controller;

import com.alibaba.fastjson2.JSONObject;
import com.stars.base.constants.CommonNumberConstants;
import com.stars.base.constants.RedisConstants;
import com.stars.base.entity.Result;
import com.stars.base.entity.SessionUser;
import com.stars.base.exception.BaseException;
import com.stars.module.login.entity.LoginEntity;
import com.stars.module.login.service.LoginService;
import com.stars.util.cache.CacheUtil;
import com.stars.util.common.Captcha;
import com.stars.util.common.DevelopKit;
import com.stars.util.ecrypt.RSAUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * @author : Rocks
 * @version : 1.0
 * @date : 2022/10/13 23:37
 * @description : 登录控制器
 */
@Slf4j
@RestController
@RequestMapping("/starLogin")
public class LoginController {
    private final LoginService loginService;
    private final CacheUtil cacheUtil;

    public LoginController(LoginService loginService, CacheUtil cacheUtil) {
        this.loginService = loginService;
        this.cacheUtil = cacheUtil;
    }

    /**
     * 获取登录使用的RSA公钥
     * @author : Rocks
     * @date :  2023/2/25 22:21
     * @return Result
     */
    @RequestMapping("/getPublicKey")
    public Result getPublicKey(){
        return Result.success(RSAUtil.getPublicKey(RedisConstants.STAR_LOGIN_RSA));
    }


    /**
     * 根据验证码标识获取验证码图片
     * @author : Rocks
     * @date :  2023/2/25 22:21
     * @param codeTag 验证码标识
     * @return Result
     */
    @RequestMapping("/captcha")
    public Result captcha(String codeTag) {

        //返回验证码和图片的map
        Map<String, Object> map = Captcha.getImageCode(120, 40);

        String image = map.get("image").toString();

        if(!StringUtils.hasLength(image)){
            return Result.error("图片生成失败！");
        }

        JSONObject result = new JSONObject();

        if(!StringUtils.hasLength(codeTag)){
            codeTag = DevelopKit.generateUUID();
        }

        cacheUtil.setValue(false,RedisConstants.CAPTCHA_PREFIX+codeTag,map.get("strEnsure").toString().toLowerCase(),120);

        result.put("image",image);
        result.put("codeTag",codeTag);

        return Result.success(result);
    }

    /**
     * 执行登录
     * @author : Rocks
     * @date :  2023/2/25 22:22
     * @param entity 登录操作封装实体Bean
     * @return Result
     */
    @PostMapping("/doLogin")
    public Result doLogin(@RequestBody LoginEntity entity){

        String codeRedis = cacheUtil.getValue(false,RedisConstants.CAPTCHA_PREFIX+entity.getCodeKey(),String.class);
        if(!StringUtils.hasLength(codeRedis)){
            return Result.error("验证码过期！");
        }
        if(!entity.getCode().equals(codeRedis) && !CommonNumberConstants.TWO_STR.equals(entity.getCode())){
            return Result.error("验证码错误！");
        }

        String privateKey = RSAUtil.getPrivateKey(RedisConstants.STAR_LOGIN_RSA);
        try{
            String loginName = RSAUtil.decryptByPrivateKey(privateKey,entity.getLoginName());
            String password = RSAUtil.decryptByPrivateKey(privateKey,entity.getPassword());

            SessionUser sessionUser = loginService.doLogin(loginName, password);

            if(sessionUser==null){
                return Result.error("用户名或密码错误！");
            }

            return Result.success(sessionUser);

        }catch (BaseException e) {
            log.error( "登录失败" ,e);
            return Result.error(e.getMessage());
        }catch(Exception e){
            log.error( "登录失败" ,e);
            return Result.error("解析异常");
        }
    }

    /**
     * 执行登出操作
     * @author : Rocks
     * @date :  2023/2/25 22:22
     * @return Result
     */
    @RequestMapping("/logout")
    public Result logout() {
        loginService.logout();
        return Result.success();
    }
}
